<?php

declare(strict_types=1);

/**
 * Contains the PropertyTest class.
 *
 * @copyright   Copyright (c) 2018 Attila Fulop
 * @author      Attila Fulop
 * @license     MIT
 * @since       2018-12-08
 *
 */

namespace Vanilo\Properties\Tests;

use Illuminate\Support\Str;
use Vanilo\Properties\Models\Property;

class PropertyTest extends TestCase
{
    /** @test */
    public function all_mutable_fields_can_be_mass_assigned()
    {
        $property = Property::create([
            'name' => 'Funkiness',
            'type' => 'text',
            'slug' => 'funkiness',
            'is_hidden' => true,
            'configuration' => ['x' => 'y', 'a' => 'b']
        ]);

        $this->assertEquals('Funkiness', $property->name);
        $this->assertEquals('text', $property->type);
        $this->assertEquals('funkiness', $property->slug);
        $this->assertEquals(['x' => 'y', 'a' => 'b'], $property->configuration);
        $this->assertTrue($property->is_hidden);
    }

    /** @test */
    public function all_mutable_fields_can_be_set()
    {
        $property = new Property();

        $property->name = 'Creepiness';
        $property->type = 'number';
        $property->slug = 'creepiness';
        $property->is_hidden = true;
        $property->configuration = ['bam' => 'zdish', 'bumm' => 'tsish'];

        $property->save();
        $property->refresh();

        $this->assertEquals('Creepiness', $property->name);
        $this->assertEquals('number', $property->type);
        $this->assertTrue($property->is_hidden);
        $this->assertEquals('creepiness', $property->slug);

        $cfg = $property->configuration;
        $this->assertIsArray($cfg);
        $this->assertEquals('zdish', $cfg['bam']);
        $this->assertEquals('tsish', $cfg['bumm']);
    }

    /** @test */
    public function slug_is_autogenerated_from_name()
    {
        $property = Property::create([
            'name' => 'Example Property',
            'type' => 'text'
        ]);

        $this->assertEquals('example-property', $property->slug);
    }

    /** @test */
    public function slug_must_be_unique()
    {
        $this->expectExceptionMessageMatches('/UNIQUE constraint failed/');

        $p1 = Property::create([
            'name' => 'Color',
            'type' => 'text',
            'slug' => 'color'
        ]);

        $p2 = Property::create([
            'name' => 'Color',
            'type' => 'text',
            'slug' => 'color'
        ]);

        $this->assertNotEquals($p1->slug, $p2->slug);
    }

    /** @test */
    public function autogenerated_slugs_are_unique()
    {
        $p1 = Property::create([
            'name' => 'RAM Size',
            'type' => 'text'
        ]);

        $p2 = Property::create([
            'name' => 'RAM Size',
            'type' => 'text'
        ]);

        $this->assertNotEquals($p1->slug, $p2->slug);
    }

    /** @test */
    public function it_can_be_retrieved_by_slug_using_the_static_finder_method()
    {
        Property::create([
            'name' => 'RAM Size',
            'slug' => 'ram',
            'type' => 'text',
        ]);

        Property::create([
            'name' => 'Screen Size',
            'slug' => 'screen',
            'type' => 'text',
        ]);

        $ram = Property::findBySlug('ram');
        $screen = Property::findBySlug('screen');

        $this->assertInstanceOf(Property::class, $ram);
        $this->assertEquals('RAM Size', $ram->name);

        $this->assertInstanceOf(Property::class, $screen);
        $this->assertEquals('Screen Size', $screen->name);
    }

    /** @test */
    public function the_hidden_scopes_can_be_used_to_query_models()
    {
        for ($i = 0; $i < 8; $i++) {
            Property::create([
                'name' => Str::ulid()->toBase58(),
                'type' => 'text',
                'is_hidden' => true,
            ]);
        }
        for ($i = 0; $i < 5; $i++) {
            Property::create([
                'name' => Str::ulid()->toBase58(),
                'type' => 'text',
                'is_hidden' => false,
            ]);
        }

        $this->assertEquals(5, Property::visibleOnes()->count());
        $this->assertEquals(8, Property::hiddenOnes()->count());
    }
}
